package com.eight.cloud.job.config;

import cn.hutool.core.util.ObjectUtil;
import com.eight.cloud.job.common.anotations.QuartzGroup;
import com.eight.cloud.job.common.anotations.QuartzJob;
import com.eight.cloud.job.model.dto.QuartzJobDto;
import com.eight.cloud.job.service.IExecutionJobService;
import com.eight.cloud.job.service.IQuartzJobService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.eight.cloud.core.global.constant.NumConstant.ZERO;
import static com.eight.cloud.core.global.constant.StrConstant.DOT;

/**
 * 加载任务到数据库
 * @ClassName: QuartzJobAspect
 * @Author: TXC
 * @Date: 2025-07-15 10:45
 **/
@Order(1)
@Component
public class QuartzJobInitializer implements ApplicationRunner {
    @Resource
    private IQuartzJobService quartzJobService;
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private IExecutionJobService executionJobService;

    private static final String LOCK_KEY = "quartz_job_init_lock";
    private static final long LOCK_EXPIRE_TIME = 30;

    @Override
    public void run(ApplicationArguments args) {
        RLock lock = redissonClient.getLock(LOCK_KEY);
        try {
            // 尝试获取分布式锁
            if (lock.tryLock(LOCK_EXPIRE_TIME, TimeUnit.SECONDS)) {
                // 获取到锁，执行任务信息添加操作
                Map<String, Object> beans = applicationContext.getBeansWithAnnotation(QuartzGroup.class);
                List<String> invokeTargets= new ArrayList<>();
                for (Object bean : beans.values()) {
                    Class<?> beanClass = bean.getClass();
                    String[] beanNames = applicationContext.getBeanNamesForType(beanClass);
                    QuartzGroup quartzGroup = beanClass.getAnnotation(QuartzGroup.class);
                    if (ObjectUtil.isNotNull(quartzGroup)) {
                        String jobGroup = quartzGroup.jobGroup();
                        Method[] methods = beanClass.getMethods();
                        for (Method method : methods) {
                            QuartzJob quartzJob = method.getAnnotation(QuartzJob.class);
                            if (ObjectUtil.isNotNull(quartzJob)) {
                                String jobName = quartzJob.jobName();
                                String description = quartzJob.description();
                                String invokeTarget = beanNames[ZERO] + DOT + method.getName();
                                QuartzJobDto quartzJobDto = new QuartzJobDto();
                                quartzJobDto.setJobName(jobName);
                                quartzJobDto.setJobGroup(jobGroup);
                                quartzJobDto.setInvokeTarget(invokeTarget);
                                quartzJobDto.setDescription(description);
                                quartzJobService.createQuartzJob(quartzJobDto);
                                invokeTargets.add(invokeTarget);
                            }
                        }
                    }
                }
                List<String> jobIds = quartzJobService.deleteQuartzJobIgnore(invokeTargets);
                executionJobService.deleteJob(jobIds);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
}
